//
//  CalendarView.m
//  parent
//
//  Created by IreWesT on 15/5/28.
//  Copyright (c) 2015年 ci123. All rights reserved.
//

#import "CalendarView.h"
#import "NSDate+convenience.h"
#import "DayModel.h"
#import "UIUtils.h"
#import "UIViewExt.h"

#define BackgroundColor UIColorMake(240, 240, 240)
#define SelectedColor UIColorMake(252, 74, 74)

CGFloat WeekSymbolHeight;
const NSArray *WeekSymbols;
const NSArray *StateColors;
const CGFloat RedDotLength = 7.0f;

@implementation CalendarView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    if (self) {
        [self setBackgroundColor:[UIColor whiteColor]];
        CGFloat width = self.frame.size.width;
        WeekSymbolHeight = 42.0f;
        self.cellWidth = width / 7;
        self.cellHeight = (self.frame.size.height - WeekSymbolHeight) / 6;
        
        self.isAnimating = NO;
        self.isTodayUpdated = YES;
        self.selectedStamp = [UIUtils todayStamp];
        self.dataDic = [[NSMutableDictionary alloc] init];
        WeekSymbols = @[@"S",@"M",@"T",@"W",@"T",@"F",@"S"];
    }
    return self;
}

#pragma mark - UI

- (void)showViews
{
    [self _initView];
}

- (void)_initView
{
    UIView *weekdayView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, WeekSymbolHeight)];
    [weekdayView setBackgroundColor:BackgroundColor];
    [self addSubview:weekdayView];
    
    for (int i = 0; i < 7; i++) {
        UILabel *weekdayLabel = [[UILabel alloc] initWithFrame:CGRectMake(i * _cellWidth, 0, _cellWidth, WeekSymbolHeight)];
        [weekdayLabel setBackgroundColor:[UIColor clearColor]];
        [weekdayLabel setText:WeekSymbols[i]];
        [weekdayLabel setTextAlignment:NSTextAlignmentCenter];
        [weekdayLabel setFont:[UIFont systemFontOfSize:12.0f]];
        [weekdayLabel setTextColor:UIColorMake(139, 140, 142)];
        [weekdayView addSubview:weekdayLabel];
    }
    
    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, WeekSymbolHeight, self.frame.size.width, _cellHeight * 6)];
    [_scrollView setBackgroundColor:BackgroundColor];
    [_scrollView setPagingEnabled:YES];
    [_scrollView setDelegate:self];
    [_scrollView setShowsHorizontalScrollIndicator:NO];
    [_scrollView setContentSize:CGSizeMake(_scrollView.width * 3, _scrollView.height)];
    [self addSubview:_scrollView];
    
    _currentMonth = [NSDate currentMonth];
    _todayMonth = _currentMonth;
    [self loadDataWithMonth:_currentMonth];
    
    if ([self.delegate respondsToSelector:@selector(showViewFinished)]) {
        [self.delegate showViewFinished];
    }
}

- (void)loadDataWithMonth:(NSDate *)month
{
    _currentMonthView = [self calendarViewWithMonth:month];
    if (_todayMonth.year == month.year && _todayMonth.month == month.month) {
        _todayMonthView = _currentMonthView;
    }else {
        _todayMonthView = [self calendarViewWithMonth:_todayMonth];
    }
    
    if (_viewsArray) {
        for (UIView *view in _viewsArray) {
            [view removeFromSuperview];
        }
        [_viewsArray removeAllObjects];
    }else {
        _viewsArray = [[NSMutableArray alloc] init];
    }
    
    [_viewsArray addObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:-1]]];
    [_viewsArray addObject:_currentMonthView];
    [_viewsArray addObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:+1]]];
    
    _selectedMonthData = _dataDic[[NSDate yearAndMonth:_currentMonth]];
    if (_todayMonth.year == month.year && _todayMonth.month == month.month) {
        _todayMonthData = _selectedMonthData;
    }else {
        _todayMonthData = _dataDic[[NSDate yearAndMonth:_todayMonth]];
    }
    [self updateViewFrame];
}

- (DayModel *)reloadDataWithMonth:(NSDate *)month
{
    [self loadDataWithMonth:month];
    
    return _selectedDayModel;
}

- (UIView *)calendarViewWithMonth:(NSDate *)month
{
    NSInteger firstWeekDay = [month firstWeekDayInMonth];
    NSInteger numRows = [self numberOfRowsWithMonth:month];
    numRows = 6;
    NSInteger numBlocks = numRows * 7;
    NSInteger numDays = [month numDaysInMonth];
    
    NSArray *data;
    if ([self.delegate respondsToSelector:@selector(getDataWithMonth:)]) {
        data = [self.delegate getDataWithMonth:month];
    }
    
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, _cellHeight * numRows)];
    view.backgroundColor = BackgroundColor;
    [_scrollView addSubview:view];
    
    if (!data || data.count <= 0) {
        return view;
    }
    
    [_dataDic setObject:data forKey:[NSDate yearAndMonth:month]];
    
    float originX = 0;
    float originY = 0;
    for (int i = 1; i <= numBlocks; i++) {
        UIView *cell = [[UIView alloc] initWithFrame:CGRectMake(originX, originY, _cellWidth, _cellHeight)];
        [cell setBackgroundColor:BackgroundColor];
        cell.layer.borderWidth = .5f;
        cell.layer.borderColor = BackgroundColor.CGColor;
        [view addSubview:cell];
        
        //weekday
        if (i >= firstWeekDay && i < (numDays + firstWeekDay)) {
            NSInteger day = i - firstWeekDay + 1;
            DayModel *model = (DayModel *)data[day - 1];
            
            UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, _cellWidth, _cellHeight)];
            [label setBackgroundColor:[UIColor clearColor]];
            [label setTextAlignment:NSTextAlignmentCenter];
            [label setFont:[UIFont systemFontOfSize:12.0f]];
            [label setTextColor:UIColorMake(125, 125, 125)];
            [label setText:[NSString stringWithFormat:@"%ld", (long)day]];
            [label setTag:1001];
            [cell setBackgroundColor:[UIColor whiteColor]];
            if (_selectedStamp == model.stamp) {
                [self clickWithView:cell];
                label.textColor = [UIColor whiteColor];
                _selectedDayModel = model;
            }
            [cell addSubview:label];
            
            if (model.hasHomework) {
                CALayer *redDot = [CALayer layer];
                redDot.backgroundColor = SelectedColor.CGColor;
                redDot.cornerRadius = RedDotLength / 2;
                redDot.frame = CGRectMake((_cellWidth - RedDotLength) / 2, _cellHeight - RedDotLength - ((_cellWidth - 12) / 2 - RedDotLength) / 2, RedDotLength, RedDotLength);
                [cell.layer addSublayer:redDot];
            }
            
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cellClick:)];
            [cell addGestureRecognizer:tap];
            cell.tag = model.stamp;
        }
        
        if (i % 7 == 0) {
            originX = 0;
            originY += _cellHeight;
        }else {
            originX += _cellWidth;
        }
    }
    
    return view;
}

- (void)updateViewFrame
{
    for (int i = 0; i < 3; i++) {
        UIView *view = (UIView *)_viewsArray[i];
        view.left = i * view.width;
    }
    
    [_scrollView setContentOffset:CGPointMake(_scrollView.width, 0) animated:NO];
    
    [UIView animateWithDuration:0.3
                          delay:0
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^(void){
                         //                         _scrollView.height = _currentMonthView.height;
                         //                         _scrollView.contentSize = CGSizeMake(_scrollView.width * 3, _scrollView.height);
                     }
                     completion:^(BOOL finished){
                         _isAnimating = NO;
                     }];
}

- (void)clickWithView:(UIView *)view {
    
    view.backgroundColor = SelectedColor;
    UILabel *label = (UILabel *)[view viewWithTag:1001];
    label.textColor = [UIColor whiteColor];
}

- (void)clickCancelWithView:(UIView *)view {
    UIView *tview = (UIView*)[view viewWithTag:_selectedStamp];
    tview.backgroundColor = [UIColor whiteColor];
    UILabel *label = (UILabel *)[view viewWithTag:1001];
    label.textColor = UIColorMake(125, 125, 125);
}

#pragma mark - Private Methods

- (NSInteger)numberOfRowsWithMonth:(NSDate *)month
{
    float lastBlock = [month numDaysInMonth] + ([month firstWeekDayInMonth]-1);
    return ceilf(lastBlock / 7);
}

- (void)showLastMonth {
    
    _isAnimating = YES;
    
    _currentMonth = [_currentMonth offsetMonth:-1];
    _currentMonthView = _viewsArray[0];
    UIView *view = _viewsArray[2];
    if (view != _todayMonthView) {
        [view removeFromSuperview];
    }
    [_viewsArray removeObject:view];
    [_viewsArray insertObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:-1]]
                      atIndex:0];
    [self updateViewFrame];
    
    _selectedMonthData = _dataDic[[NSDate yearAndMonth:_currentMonth]];
    
    if ([self.delegate respondsToSelector:@selector(moveMonth:withOffset:)]) {
        [self.delegate moveMonth:_currentMonth withOffset:-1];
    }
}

- (void)showNextMonth {
    
    _isAnimating = YES;
    
    _currentMonth = [_currentMonth offsetMonth:+1];
    _currentMonthView = _viewsArray[2];
    UIView *view = _viewsArray[0];
    if (view != _todayMonthView) {
        [view removeFromSuperview];
    }
    [_viewsArray removeObject:view];
    [_viewsArray addObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:+1]]];
    
    [self updateViewFrame];
    
    _selectedMonthData = _dataDic[[NSDate yearAndMonth:_currentMonth]];
    
    if ([self.delegate respondsToSelector:@selector(moveMonth:withOffset:)]) {
        [self.delegate moveMonth:_currentMonth withOffset:+1];
    }
    
}

- (void)returnTodayMonth
{
    if (_isAnimating) {
        return;
    }
    
    _isAnimating = YES;
    
    _currentMonth = [NSDate currentMonth];
    _selectedStamp = [UIUtils todayStamp];
    _selectedMonthData = _todayMonthData;
    
    for (DayModel *model in _todayMonthData) {
        if (_selectedStamp == model.stamp) {
            _selectedDayModel = model;
        }
    }
    
    for (UIView *view in _todayMonthView.subviews) {
        [view.layer setBorderColor:[UIColor whiteColor].CGColor];
        if (view.tag == _selectedStamp) {
            [self clickWithView:view];
        }
    }
    
    for (UIView *view in _viewsArray) {
        if (view != _todayMonthView) {
            [view removeFromSuperview];
        }
    }
    
    [_viewsArray removeAllObjects];
    
    [_viewsArray addObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:-1]]];
    [_viewsArray addObject:_todayMonthView];
    [_viewsArray addObject:[self calendarViewWithMonth:[_currentMonth offsetMonth:+1]]];
    
    _currentMonthView = _todayMonthView;
    [self updateViewFrame];
    
    if ([self.delegate respondsToSelector:@selector(dayClick:)]) {
        [self.delegate dayClick:_selectedDayModel];
    }
}

- (void)turnLastMonth {
    
    if (_isAnimating) {
        return;
    }
    
    [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x - _scrollView.width, _scrollView.contentOffset.y) animated:YES];
}

- (void)turnNextMonth {
    
    if (_isAnimating) {
        return;
    }
    
    [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x + _scrollView.width, _scrollView.contentOffset.y) animated:YES];
}

#pragma mark - Action

- (void)cellClick:(UITapGestureRecognizer *)tap
{
    if (_selectedStamp == tap.view.tag) {
        return;
    }
    
    [self clickWithView:tap.view];
    
    UIView *lastView = [_currentMonthView viewWithTag:_selectedStamp];
    if (lastView) {
        [self clickCancelWithView:lastView];
    }else {
        for (UIView *view in ((UIView *)_viewsArray[0]).subviews) {
            [self clickCancelWithView:view];
        }
        for (UIView *view in ((UIView *)_viewsArray[2]).subviews) {
            [self clickCancelWithView:view];
        }
    }
    
    _selectedStamp = tap.view.tag;
    
    for (DayModel *model in _selectedMonthData) {
        if (model.stamp == _selectedStamp) {
            _selectedDayModel = model;
            break;
        }
    }
    
    if ([self.delegate respondsToSelector:@selector(dayClick:)]) {
        [self.delegate dayClick:_selectedDayModel];
    }
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    
    CGFloat x = scrollView.contentOffset.x;
    if (x == scrollView.frame.size.width || _isAnimating) {
        return;
    }
    
    if (x >= scrollView.frame.size.width * 2) {//next month
        [self showNextMonth];
    }else if (x < scrollView.frame.size.width){//last month
        [self showLastMonth];
    }
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
    
    CGFloat x = scrollView.contentOffset.x;
    if (x == scrollView.frame.size.width || _isAnimating) {
        return;
    }
    
    if (x >= scrollView.frame.size.width * 2) {//next month
        [self showNextMonth];
    }else if (x < scrollView.frame.size.width){//last month
        [self showLastMonth];
    }
}

@end
